﻿using System;
using System.Threading;
using System.Threading.Tasks;
using RestSharp;

namespace Lasalara.Controls
{
    public static class RestExtension
    {

        public static Task<IRestResponse<T>> ExecuteAsync<T>(this IRestClient client, IRestRequest request) where T : new()
        {
            return client.ExecuteAsync<T>(request, CancellationToken.None);
        }

        public static Task<IRestResponse<T>> ExecuteAsync<T>(this IRestClient client, IRestRequest request, CancellationToken token) where T : new()
        {
            var taskCompletionSource = new TaskCompletionSource<IRestResponse<T>>();
            RestRequestAsyncHandle asyncHandle = null;

            token.Register(() =>
            {
                if (asyncHandle != null)
                    asyncHandle.Abort();

                taskCompletionSource.TrySetCanceled();
            });

            if (!token.IsCancellationRequested)
                asyncHandle = client.ExecuteAsync(request, (IRestResponse<T> response, RestRequestAsyncHandle handle) => taskCompletionSource.TrySetResult(response));
            else
                taskCompletionSource.TrySetCanceled();


            return taskCompletionSource.Task;
        }

        public static Task<IRestResponse> ExecuteAsync(this IRestClient client, IRestRequest request)
        {
            return client.ExecuteAsync(request, CancellationToken.None);
        }

        public static Task<IRestResponse> ExecuteAsync(this IRestClient client, IRestRequest request, CancellationToken token)
        {
            var taskCompletionSource = new TaskCompletionSource<IRestResponse>();

            RestRequestAsyncHandle asyncHandle = null;

            token.Register(() =>
            {
                if (asyncHandle != null)
                    asyncHandle.Abort();

                taskCompletionSource.TrySetCanceled();
            });

            if (!token.IsCancellationRequested)
                asyncHandle = client.ExecuteAsync(request, (response, handle) => taskCompletionSource.TrySetResult(response));
            else
                taskCompletionSource.TrySetCanceled();

            return taskCompletionSource.Task;
        }

    }
}
